package com.blacktech.dbu.meta.service;

import com.blacktech.dbu.core.util.DDLTemplateUtil;
import com.blacktech.dbu.meta.entity.DbuSchema;
import com.blacktech.dbu.meta.entity.DbuTable;
import freemarker.core.TemplateClassResolver;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * 基于模板引擎的DDL脚本生成服务
 *
 * @author yanyunsong
 */
@Service
public class TemplateDDLScriptService {

    private final Configuration configuration;

    @Autowired
    public TemplateDDLScriptService(Configuration configuration) {
        this.configuration = configuration;
        // 设置模板加载路径
        this.configuration.setClassForTemplateLoading(this.getClass(), "/templates/ddl");
        // 允许使用unsafeMethods
        this.configuration.setAPIBuiltinEnabled(true);
        this.configuration.setNewBuiltinClassResolver(TemplateClassResolver.ALLOWS_NOTHING_RESOLVER);
    }
    
    @PostConstruct
    public void configure() throws TemplateException {
        // 在FreeMarker配置中注册工具类
        configuration.setSharedVariable("DDLTemplateUtil", DDLTemplateUtil.class);
    }

    /**
     * 生成MySQL单表DDL脚本
     * @param table 数据表
     * @param schema 数据库模式
     * @return DDL脚本
     */
    public String generateMySQLTableDDL(DbuTable table, DbuSchema schema) throws IOException, TemplateException {
        Template template = configuration.getTemplate("mysql-table.sql.ftl");
        Map<String, Object> dataModel = new HashMap<>();
        dataModel.put("table", table);
        dataModel.put("schema", schema);
        return FreeMarkerTemplateUtils.processTemplateIntoString(template, dataModel);
    }

    /**
     * 生成Oracle单表DDL脚本
     * @param table 数据表
     * @param schema 数据库模式
     * @return DDL脚本
     */
    public String generateOracleTableDDL(DbuTable table, DbuSchema schema) throws IOException, TemplateException {
        Template template = configuration.getTemplate("oracle-table.sql.ftl");
        Map<String, Object> dataModel = new HashMap<>();
        dataModel.put("table", table);
        dataModel.put("schema", schema);
        return FreeMarkerTemplateUtils.processTemplateIntoString(template, dataModel);
    }

    /**
     * 生成数据库模式的DDL脚本
     * @param schema 数据库模式
     * @return DDL脚本
     */
    public String generateSchemaDDL(DbuSchema schema) throws IOException, TemplateException {
        StringWriter writer = new StringWriter();
        
        writer.append("-- Schema: ").append(schema.getSchemaName()).append("\n");
        writer.append("-- Generated by Database Universe\n\n");
        
        // 生成该模式下所有表的DDL
        for (DbuTable table : schema.getTables()) {
            // 根据数据库类型选择合适的模板
            String tableDDL;
            switch (schema.getDbType()) {
                case mysql:
                case oceanBase_mysql:
                    tableDDL = generateMySQLTableDDL(table, schema);
                    break;
                case oracle:
                case oceanBase_oracle:
                    tableDDL = generateOracleTableDDL(table, schema);
                    break;
                default:
                    tableDDL = generateMySQLTableDDL(table, schema);
                    break;
            }
            writer.append(tableDDL).append("\n\n");
        }
        
        return writer.toString();
    }
}